package com.alexeyhanin.tapestry.goodies.util.select;

import static com.alexeyhanin.tapestry.goodies.util.StringUtil.notNullString;
import org.apache.tapestry5.OptionGroupModel;
import org.apache.tapestry5.OptionModel;
import org.apache.tapestry5.internal.OptionModelImpl;
import org.apache.tapestry5.ioc.services.PropertyAccess;
import org.apache.tapestry5.util.AbstractSelectModel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author aha
 * @since 2009.5.11
 *        $Id: GenericSelectModel.java 15 2009-11-30 17:52:21Z gagarin61 $
 */
public class GenericSelectModel<T> extends AbstractSelectModel {

    private PropertyAdapter labelAdapter;

    private List<T> list;

    public GenericSelectModel(String label, String labelFormat, PropertyAccess propertyAccess, List<T> list) {
        this.list = list;
        if (list != null && !list.isEmpty()) {
            final T firstElement = list.iterator().next();
            final Class<?> listType = firstElement.getClass();

            if (labelFormat != null) {
                final FormattingPropertyAdapterFactory adapterFactory =
                        new FormattingPropertyAdapterFactory(listType, propertyAccess);
                labelAdapter = adapterFactory.create(labelFormat);
            } else if (label != null) {
                labelAdapter = new SimplePropertyAdapter(label, listType, propertyAccess);
            }
        }
    }

    public List<OptionGroupModel> getOptionGroups() {
        return null;
    }

    public List<OptionModel> getOptions() {
        final List<OptionModel> options;
        if (list == null || list.isEmpty()) {
            options = Collections.emptyList();
        } else {
            options = new ArrayList<OptionModel>(list.size());
            for (T item : list) {
                final Object labelObject;
                if (labelAdapter == null) {
                    labelObject = item;
                } else {
                    labelObject = labelAdapter.get(item);
                }
                final String label = notNullString(labelObject);
                final OptionModel option = new OptionModelImpl(label, item);
                options.add(option);
            }
        }
        return options;
    }
}
